package com.turnengine.client.local.action;

import static com.turnengine.client.local.action.enums.ActionTargetType.SOURCE;
import static com.turnengine.client.local.action.enums.ActionTargetType.TARGET;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import com.turnengine.client.local.action.bean.IAction;
import com.turnengine.client.local.action.bean.IActionCondition;
import com.turnengine.client.local.action.bean.IActionTarget;
import com.turnengine.client.local.unit.interfaces.IUnitIdContainer;

public class ActionDefinition implements IActionDefinition, IUnitIdContainer {

	private final IAction action;
	private volatile IActionTarget source = null;
	private volatile IActionTarget target = null;
	private final List<IActionCondition> sourceList = new CopyOnWriteArrayList<IActionCondition>();
	private final List<IActionCondition> targetList = new CopyOnWriteArrayList<IActionCondition>();

	public ActionDefinition(IAction action) {
		this.action = action;
	}

	@Override
	public int getUnitId() {
		return getAction().getActionId();
	}

	@Override
	public IAction getAction() {
		return action;
	}

	@Override
	public IActionTarget getSource() {
		if (source == null) {
			throw new IllegalStateException("source not set (mandatory)");
		}
		return source;
	}

	@Override
	public IActionTarget getTarget() {
		return target;
	}

	@Override
	public boolean hasTarget() {
		return target != null;
	}

	@Override
	public List<IActionCondition> getConditions() {
		List<IActionCondition> list = new ArrayList<IActionCondition>();
		list.addAll(sourceList);
		list.addAll(targetList);
		return list;
	}

	@Override
	public void setSource(IActionTarget source) {
		if (source.getActionId() != getAction().getActionId()) {
			throw new IllegalArgumentException("source=" + source + ", action=" + getAction());
		}
		if (!source.getTargetType().equals(SOURCE)) {
			throw new IllegalArgumentException("source=" + source + ", action=" + getAction());
		}
		this.source = source;
	}

	@Override
	public void setTarget(IActionTarget target) {
		if (target.getActionId() != getAction().getActionId()) {
			throw new IllegalArgumentException("target=" + target + ", action=" + getAction());
		}
		if (!target.getTargetType().equals(TARGET)) {
			throw new IllegalArgumentException("target=" + target + ", action=" + getAction());
		}
		this.target = target;
	}

	@Override
	public void addCondition(IActionCondition condition) {
		if (source == null) {
			throw new IllegalStateException("source not set (mandatory)");
		}
		if (condition.getActionId() != getAction().getActionId()) {
			throw new IllegalArgumentException("condition=" + condition + ", action=" + getAction());
		}
		if (condition.getTargetType().equals(SOURCE)) {
			sourceList.add(condition);
		}
		if (condition.getTargetType().equals(TARGET)) {
			targetList.add(condition);
		}
	}

	@Override
	public List<IActionCondition> getSourceConditions() {
		return sourceList;
	}

	@Override
	public List<IActionCondition> getTargetConditions() {
		return targetList;
	}

}
